﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

///==============================
//作者：李彰楠
//日期：2020/7/5
//
//名称：ManagerBase
//
//描述：管理在当前Manager注册了ID的MonoBase
//
///==============================
namespace gameFramework_v1dot0_lzn
{
    //链表节点
    public class EventNode
    {
        //当前脚本
        public MonoBase data;
        //指针,下一个节点
        public EventNode next;

        public EventNode(MonoBase _tempMono)
        {
            this.data = _tempMono;

            this.next = null;
        }

    }

    /// <summary>
    /// ManagerBase：主要负责消息的存储和处理
    /// </summary>
    public class ManagerBase : MonoBase
    {
        #region 链表数据结构，注册与反注册，响应事件
        //存储链表数据结构——存储注册消息key value
        public Dictionary<ushort,EventNode> eventTree = new Dictionary<ushort, EventNode>();
        private void Awake()
        {
            eventTree.Clear();
        }
        /// <summary>
        /// 注册接口——一个脚本注册多个MsgId
        /// </summary>
        /// <param name="_mono">要注册的脚本</param>
        /// <param name="_msgs">脚本可以注册多个msg</param>
        public void RegistMsg(MonoBase _mono, params ushort[] _msgs)
        {
            //对每一个MsgId
            for (int i = 0; i < _msgs.Length; i++)
            {
                //创建一个新的节点
                EventNode tempNode = new EventNode(_mono);
                //进行注册
                //Debug.Log(_msgs[i] + tempNode.data.name);
                RegistMsg(_msgs[i], tempNode);
                
            }
        }

        /// <summary>
        /// 注册接口——一个脚本注册一个MsgId
        /// </summary>
        /// <param name="_id">根据MsgId</param>
        /// <param name="">node链表</param>
        public void RegistMsg(ushort _id, EventNode _eventNode)
        {
            //如果数据链路里面没有消息id，直接添加
            if (!eventTree.ContainsKey(_id))
            {
                //Debug.Log("EventTree:链表里面没有当前id"+_id);
                eventTree.Add(_id, _eventNode);
            }
            else
            {
                Debug.Log("EventTree:链表里面有当前id" + _id);
                //Debug.Log(eventTree[_id].data.name);
                EventNode tempNode = eventTree[_id];

                //找到最后一个链表节点并赋值
                while (tempNode.next != null)
                {
                    Debug.Log(tempNode.data.name);
                    tempNode = tempNode.next;
                    Debug.Log(tempNode.data.name);
                }
                tempNode.next = _eventNode;
            }
        }

        /// <summary>
        /// 去掉一个脚本（一个脚本可能对应多个id）
        /// </summary>
        /// <param name="_mono"></param>
        /// <param name="_msgs"></param>
        public void unRegistMsg(MonoBase _mono,params ushort[] _msgs)
        {//params——可变数组，参数；用于表示类型相同，但参数数量不确定
            for (int i = 0; i < _msgs.Length; i++)
            {
                unRegistMsg(_msgs[i],_mono);
            }
        }

        /// <summary>
        /// 去掉一个消息链
        /// </summary>
        /// <param name="_id"></param>
        /// <param name="_node"></param>
        public void unRegistMsg(ushort _id, MonoBase _node)
        {
            if (!eventTree.ContainsKey(_id))
            {
                Debug.LogError("Not contain id: " + _id);
            }
            else
            {
                EventNode tempNode = eventTree[_id];
                //链表的第一个节点,两种情况
                if (tempNode.data == _node)
                {
                    EventNode header = tempNode;//当前节点的副本
                    if (tempNode.next != null)
                    {//已经存在消息,第一个节点后面不为空
                        header.data = tempNode.next.data;//将当前节点的副本下移
                        header.next = tempNode.next.next;
                        //eventTree[_id] = tempNode.next;//
                        //header.next = null;//把第一个直接置为null
                    }
                    else//后面没有节点了（只有一个节点）
                    {
                        eventTree.Remove(_id);
                    }
                }
                else//去掉尾部和中间的节点
                {
                    while (tempNode.next != null && tempNode.next.data != _node)//下一个不为空，且不是要查找的对象
                    {
                        tempNode = tempNode.next;
                    }
                    //已经找到对应节点

                    //没有引用，会自动释放
                    if (tempNode.next.next != null)
                    {//去掉中间节点
                        tempNode.next = tempNode.next.next;
                    }
                    else
                    {//去掉尾部节点
                        tempNode.next = null;
                    }
                }
            }
        }

        /// <summary>
        /// 来了通知，处理整个消息链表
        /// </summary>
        /// <param name="_tempMsg"></param>
        public override void ProcessEvent(MessageBase _tempMsg)
        {
            if (!eventTree.ContainsKey(_tempMsg.msgId))
            {//判断节点是否进行了注册
                Debug.LogError("Msg not Contains msgId == " + _tempMsg.msgId);
                Debug.LogError("Msg Manager == " + _tempMsg.GetManager());
                return;
            }
            else
            {
                EventNode tempNode = eventTree[_tempMsg.msgId];//获取对应id的链表的头节点
                //通知全部脚本
                do
                {
                    tempNode.data.ProcessEvent(_tempMsg);
                    tempNode = tempNode.next;
                } while (tempNode != null);

            }
        }
        #endregion



    }

}

